﻿using UnityEngine;
using UnityEditor;
using System.IO;

namespace MyAssetBundles {
    public class MyAssetBundlesWindow : EditorWindow {
        static MyAssetBundlesWindow _window = null;
        [MenuItem("Window/MyAssetBundles")]
        static void CreateAssetBundlesWindow ()
        {
            if (_window != null)
            {
                _window.Focus();
            }else
            {
                _window = GetWindowWithRect<MyAssetBundlesWindow>(new Rect(0, 0, 500, 400), true, "Asset Bundles", true);
                _window.Show();
            }
        }

        public bool _isLoad = false;
        public string _versionFileName = "";
        public MyAssetBundlesVersions _versions;
        public string _newVersion;
        Vector2 _scrollPos;
        void OnGUI ()
        {
            GUILayout.Label("Version", EditorStyles.boldLabel);
            GUIStyle style = GUIStyle.none;
            style.wordWrap = true;
            EditorGUILayout.LabelField("Platform", MyAssetBundlesConfig.PlatformName, style);
            EditorGUILayout.LabelField("Path", _isLoad ? _versionFileName : "null", style);
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Create"))
            {
                CreateVersionFile();
                return;
            }

            if (GUILayout.Button("Load"))
            {
                LoadVersionFile();
                return;
            }

            if (GUILayout.Button("Clean"))
            {
                CleanVersionFile();
                return;
            }
            EditorGUILayout.EndHorizontal();
            
            if (_isLoad)
            {
                GUILayout.Label("Operation", EditorStyles.boldLabel);
                EditorGUILayout.BeginHorizontal();
                _newVersion = EditorGUILayout.TextField("Add version", _newVersion);
                if (GUILayout.Button("Run"))
                {
                    RunAssetBundles();
                    return;
                }
                EditorGUILayout.EndHorizontal();

                GUILayout.Label("Info", EditorStyles.boldLabel);
                _scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
                foreach (var item in _versions)
                {
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField(item.version);
                    EditorGUILayout.LabelField(item.updateMode == MyAssetBundlesUpdateMode.Force ? "Force" : "Silence");
                    EditorGUILayout.LabelField(Path.GetFileName(item.compressPackage));
                    EditorGUILayout.LabelField(item.decompressSize.ToString());
                    EditorGUILayout.LabelField(item.compressSize.ToString());
                    if (GUILayout.Button("Unpack"))
                    {
                        UnpackPackage(item);
                        return;
                    }

                    if (GUILayout.Button("Remove"))
                    {
                        RemovePackage(item);
                        return;
                    }
                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.EndScrollView();
            }
        }

        public string _defaultName = "civ";
        public string _defalutExtension = "version";
     //   public string _defaultDirectory = "E:\\unityAssetBundles\\AssetBundles-master";
        public string _defaultDirectory = "";
        void CreateVersionFile ()
        {
            Debug.Log("Create version file");

            string savePath = EditorUtility.SaveFilePanel("save path", _defaultDirectory, _defaultName, _defalutExtension);
            if (savePath == "") return;
            FileStream fStream = File.Create(savePath);
            fStream.Close();
            LoadVersionInfo(savePath);
        }
        
        void LoadVersionFile ()
        {
            Debug.Log("Load version file");
            string path = EditorUtility.OpenFilePanel("Load Version File", _defaultDirectory, _defalutExtension);
            if (path.Length == 0) return;
            LoadVersionInfo(path);
        }

        void CleanVersionFile ()
        {
            Debug.Log("Clean version file");
            _versionFileName = null;
            _versions = null;
            _isLoad = false;
        }

        void LoadVersionInfo (string path)
        {
            _versionFileName = path;
            _versions = new MyAssetBundlesVersions(Path.GetDirectoryName(_versionFileName));
            _versions.LoadLocalPath(_versionFileName);
            _isLoad = true;
        }

        void RunAssetBundles ()
        {
            if (_newVersion == null || _newVersion.Length == 0)
            {
                EditorUtility.DisplayDialog("Error", "版本号不能为空", "OK");
                return;
            }

            if (_versions.GetListWithVersion(_newVersion).Count > 0)
            {
                EditorUtility.DisplayDialog("Error", "已存在相同版本号", "OK");
                return;
            }
            
            string assetPath = MyAssetBundlesUtil.PathCombine("AssetBundles", MyAssetBundlesConfig.PlatformName);
            if (Directory.Exists(assetPath))
                Directory.Delete(assetPath, true);
            Directory.CreateDirectory(assetPath);
            BuildPipeline.BuildAssetBundles(assetPath, BuildAssetBundleOptions.UncompressedAssetBundle, EditorUserBuildSettings.activeBuildTarget);

            int forceUpdateNum = RunAssetBundlesWithMode(MyAssetBundlesUpdateMode.Force, assetPath);
            int silenceUpdateNum = RunAssetBundlesWithMode(MyAssetBundlesUpdateMode.Silence, assetPath);
            if (forceUpdateNum + silenceUpdateNum > 0)
            {
                _newVersion = "";
                EditorUtility.DisplayDialog(null, "Generate Asset Bundle Success", "OK");
            }else
            {
                EditorUtility.DisplayDialog(null, "无差异文件", "OK");
            }
        }

        int RunAssetBundlesWithMode (MyAssetBundlesUpdateMode updateMode, string assetPath)
        {
            AnalysisFolder analysis = FolderMgr.Create<AnalysisFolder>();
            analysis.Init(updateMode);
            analysis.Generate(assetPath, null);

            ContrastFolder contrast = FolderMgr.Create<ContrastFolder>();
            contrast.Init(analysis);
            contrast.Generate(_versionFileName, FolderProgress.Create<ContrastFolderProgress>());

            int contrastNum = contrast.GetContrastNumber();
            if (contrastNum > 0)
            {
                string packFileName = string.Format("Civ_Pack_{0}.{1}.{2}{3}",
                    MyAssetBundlesConfig.PlatformName,
                    _newVersion,
                    updateMode,
                    MyAssetBundlesConfig.PackageExtension
                );
                MyVersionOperation operation = new MyVersionOperation();
                operation.updateMode = updateMode;
                operation.version = _newVersion;
                operation.compressPackage = packFileName;
                operation.savePath = _versions._packageDirectory;

                PackFolder pack = FolderMgr.Create<PackFolder>();
                pack.Init(contrast);
                pack.Generate(operation.decompressPackage, FolderProgress.Create<PackFolderProgress>());

                CompressFolder compress = FolderMgr.Create<CompressFolder>();
                compress._inTotalSize = pack._packageSize;
                compress._inPath = operation.decompressPackage;
                compress.Generate(operation.compressPackage, FolderProgress.Create<CompressFolderProgress>());

                operation.decompressSize = pack._packageSize;
                operation.compressSize = compress._outTotalSize;
                _versions.AddVersion(operation);
            }
            FolderMgr.DestroyAll();
            return contrastNum;
        }

        void UnpackPackage (MyVersionOperation operation)
        {
            string folderName = Path.GetFileNameWithoutExtension(operation.compressPackage);
            string folderDir = Path.GetDirectoryName(operation.compressPackage);
            string extractPath = MyAssetBundlesUtil.PathCombine(folderDir, folderName);
            if (Directory.Exists(extractPath))
            {
                bool isOK = EditorUtility.DisplayDialog("警告", "存在文件夹:" + folderName + ".是否覆盖?", "OK", "Cancel");
                if (isOK)
                    Directory.Delete(extractPath, true);
                else
                {
                    for (int i = 1; ; i++)
                    {
                        string temp = string.Format("{0}_{1}", extractPath, i);
                        if (!Directory.Exists(temp))
                        {
                            extractPath = temp;
                            break;
                        }
                    }
                }
            }

            DecompressFolder decompress = FolderMgr.Create<DecompressFolder>();
            decompress._inPath = operation.compressPackage;
            decompress._inTotalSize = operation.compressSize;
            decompress._outTotalSize = operation.decompressSize;
            decompress.Generate(operation.decompressPackage, FolderProgress.Create<DecompressFolderProgress>());

            AnalysisFolder analysis = FolderMgr.Create<AnalysisFolder>();
            analysis.Init(operation.updateMode);
            analysis.Generate(operation.decompressPackage, null);
            
            UnpackFolder unpack = FolderMgr.Create<UnpackFolder>();
            unpack.Init(analysis);
            unpack.Generate(extractPath, FolderProgress.Create<UnpackFolderProgress>());
            FolderMgr.DestroyAll();
            
            Debug.Log("----- Extract End -----");
            EditorUtility.DisplayDialog(null, "unpack succeed", "OK"); 
        }

        void RemovePackage (MyVersionOperation operation)
        {
            bool ret = _versions.RemoveVersion(operation);
            if (!ret) return;
            if (File.Exists(operation.compressPackage))
                File.Delete(operation.compressPackage);
            Debug.Log("delete version " + operation.version);
        }
    }
}
